# 导入
import os
import time
import tkinter
import tkinter.filedialog
import pygame   # pip
import mutagen
import wave
import pylab as pl
import numpy as np
from pydub import AudioSegment
import thulac
from collections import Counter

# 引入停用此表，存为数组
stpwrd_dic = open(r"stop_words.txt", 'rb')
stpwrd_content = stpwrd_dic.read()
# 将停用词表转换为list
stpwrdlst = stpwrd_content.splitlines()
stpwrd_dic.close()

thu1 = thulac.thulac(seg_only=True)  # 默认模式
texts = []
def countFreq(rows):
    global texts
    if(texts==[]):
        for row in rows:
            text = thu1.cut(row, text=True)
            texts.append(text)
    count = Counter(texts)
    result = sorted(count.items(), key=lambda x: x[1], reverse=True)
    return result

root = tkinter.Tk()
root.title('音乐播放器')
root.geometry('800x800+500+100')
root.resizable(False,False)  # 不能拉伸
root.configure(bg='Pink')
folder =''
res = []
num = 0
now_music = ''
onoff=0
ischanging=True
seconds=0
now=0
class GetInfo():
    '''获取歌曲信息'''
    def __init__(self, path):
        songFile = mutagen.File(path)
        self.getTitle(songFile, path)
        self.getArtist(songFile)
        self.getAlbum(songFile)
        self.getLength(songFile)

    def getTitle(self, songFile, path):
        '''获取歌曲名
        songFile:文件对象
        path:文件地址
        '''
        try:
            self.title = str(songFile.tags['TIT2'])
        except:
            filename = os.path.basename(path)  # 从地址中获取文件名
            self.title = filename.split('.')[0]  # 去掉文件名后缀

    def getArtist(self,songFile):
        '''获取歌手名
        songFile:文件对象
        '''
        try:
            self.artist=str(songFile.tags['TPE1'])
        except:
            self.artist=''

    def getAlbum(self,songFile):
        '''获取专辑名
        songFile:文件对象
        '''
        try:
            self.album=str(songFile.tags['TALB'])
        except:
            self.album=''

    def getLength(self,songFile):
        '''获取文件播放时时长'''
        timeLength = int(songFile.info.length)
        mintime = timeLength//60  #转换为分钟
        sectime = timeLength % 60 #剩余的转换为秒
        if sectime < 10:
            sectime='0'+ str(sectime)
        else:
            sectime=str(sectime)
        self.length=str(mintime)+":"+sectime

def getMusicInfor():
    path = res[num]
    song = GetInfo(path)
    print(song)
    print(song.title,song.artist,song.album,song.length)
    ret=[]
    ret.append("名称"+song.title)
    ret.append("艺术家" + song.artist)
    ret.append("专辑" + song.album)
    ret.append("长度" + song.length)
    var2 = tkinter.StringVar()
    var2.set(ret)
    lb = tkinter.Listbox(root, listvariable=var2)
    lb.place(x=210, y=190, width=150, height=260)


def buttonChooseClick():
    """
    添加文件夹
    :return:
    """
    global folder
    global res
    if not folder:
        folder = tkinter.filedialog.askdirectory()
        musics = [folder + '\\' + music
                  for music in os.listdir(folder) \
\
                  if music.endswith(('.wav'))]
        ret = []
        for i in musics:
            ret.append(i.split('\\')[1:])
            res.append(i.replace('\\','/'))

        var2 = tkinter.StringVar()
        var2.set(ret)
        lb = tkinter.Listbox(root,listvariable=var2)
        lb.place(x=50,y=190,width=150,height=260)

    if not folder:
        return

    global playing
    playing = True
    # 根据情况禁用和启用相应的按钮
    buttonPlay['state'] = 'normal'
    # buttonPause['state'] = 'normal'
    pause_resume.set('播放')


def jump_to1():
    if(scale1.get()<seconds):
        pygame.mixer.music.play(1, scale1.get())
        print("跳至第：%d 秒"%scale1.get()) #超过当前歌曲长度自动从头播放

# 开始播放
def buttonPlayClick():
    """
    点击播放
    :return:
    """
    global seconds
    global num
    path = res[num]
    song = GetInfo(path)
    songlen=song.length
    min=str(songlen).split(":")
    seconds=int(min[0])*60+int(min[1])
    buttonNext['state'] = 'normal'
    buttonPrev['state'] = 'normal'
    buttonFreq['state'] = 'normal'
    buttonPic['state'] = 'normal'
    buttonJump['state'] = 'normal'
    buttonFreq['state'] = 'normal'
    # 选择要播放的音乐文件夹
    if pause_resume.get() == '播放':
        getMusicInfor()
        showLrc()
        pause_resume.set('暂停')
        global folder

        if not folder:
            folder = tkinter.filedialog.askdirectory()

        if not folder:
            return

        global playing
        global onoff

        playing = True
        if len(res):
            pygame.mixer.init()
            global onoff
            if not pygame.mixer.music.get_busy():
                netxMusic = res[num]
                print(netxMusic)
                print(num)
                pygame.mixer.music.load(netxMusic.encode())
                # 播放
                pygame.mixer.music.play(1)

    elif pause_resume.get() == '暂停':
        # pygame.mixer.init()
        pygame.mixer.music.pause()
        pause_resume.set('继续')

    elif pause_resume.get() == '继续':
        # pygame.mixer.init()
        pygame.mixer.music.unpause()
        pause_resume.set('暂停')


def showLrc():
    path = res[num]
    x = path.split("/")
    name = x[-1][:-4]
    pathl="./qqmusic/lrc/"+name+".lrc"
    """读文件"""
    # 打开文件
    if(os.path.exists(pathl)):
        file = open(pathl, "r", encoding="utf-8")
        # 读取文件全部内容
        musiclrc = file.readlines()
        file.close()
    else:
        musiclrc=["暂无歌词"]
    var2 = tkinter.StringVar()
    var2.set(musiclrc)
    lb = tkinter.Listbox(root, listvariable=var2)
    lb.place(x=50, y=470, width=300, height=400)

def buttonNextClick():
    """
    下一首
    :return:
    """
    global playing
    playing = False
    pygame.mixer.music.stop()
    global num
    num+=1
    if len(res) == num:
        num = 0
    getMusicInfor()
    showLrc()
    playing = True
    global onoff
    if not pygame.mixer.music.get_busy():
        netxMusic = res[num]
        print(netxMusic)
        print(num)
        pygame.mixer.music.load(netxMusic.encode())
        # 播放
        pygame.mixer.music.play(1)


def closeWindow():
    """
    关闭窗口
    :return:
    """
    # 修改变量，结束线程中的循环

    global playing

    playing = False

    time.sleep(0.3)

    try:

        # 停止播放，如果已停止，

        # 再次停止时会抛出异常，所以放在异常处理结构中

        pygame.mixer.music.stop()

        pygame.mixer.quit()

    except:

        pass

    root.destroy()


def control_voice(value=0.5):
    """
    声音控制
    :param value: 0.0-1.0
    :return:
    """
    pygame.mixer.music.set_volume(float(value))
    # netxMusic = res[num]
    # pygame.mixer.music.load(netxMusic.encode())
    # # 播放
    # pygame.mixer.music.play(1)


def buttonPrevClick():
    """
    上一首
    :return:
    """
    global playing

    playing = False

    pygame.mixer.music.stop()
    #
    # pygame.mixer.quit()
    global num
    # num += 1
    # num -= 1
    if num == 0:
        num = len(res) - 1
        # num -= 1
    elif num == len(res) - 1:
        num -= 1
    else:
        num -= 1
        # num -= 1
    print(num)

    playing = True
    getMusicInfor()
    showLrc()
    if not pygame.mixer.music.get_busy():
        netxMusic = res[num]
        print(netxMusic)
        print(num)
        pygame.mixer.music.load(netxMusic.encode())
        # 播放
        pygame.mixer.music.play(1)

def buttonShowPic():
    route=res[num]
    print("++",route)
    # 打开WAV文档
    f = wave.open(route, "rb")
    # 读取格式信息
    # (nchannels, sampwidth, framerate, nframes, comptype, compname)
    params = f.getparams()
    nchannels, sampwidth, framerate, nframes = params[:4]
    # 读取波形数据
    str_data = f.readframes(nframes)
    f.close()
    # 将波形数据转换为数组
    wave_data = np.fromstring(str_data, dtype=np.short)
    wave_data.shape = -1, 2
    wave_data = wave_data.T
    time = np.arange(0, nframes) * (1.0 / framerate)
    # 绘制波形
    pl.subplot(211)
    pl.plot(time, wave_data[0])
    pl.subplot(212)
    pl.plot(time, wave_data[1], c="g")
    pl.xlabel("time (seconds)")
    pl.show()
def buttonWordFreq():
    path = res[num]
    song = GetInfo(path)
    pathl = "./qqmusic/lrc/" + song.title + ".lrc"
    """读文件"""
    # 打开文件
    file = open(pathl, "r", encoding="utf-8")
    # 读取文件全部内容
    musiclrc = file.readlines()
    file.close()
    all=[]
    print(musiclrc)
    for i in musiclrc:
        if("\n" != i):
            x=i.split(']')
            all.append(x[1])
    result=countFreq(all)
    var2 = tkinter.StringVar()
    var2.set(result)
    lb = tkinter.Listbox(root, listvariable=var2)
    lb.place(x=470, y=100, width=300, height=500)

# 窗口关闭
root.protocol('WM_DELETE_WINDOW', closeWindow)

# 添加按钮
buttonChoose = tkinter.Button(root,text='添加',command=buttonChooseClick)
# 布局
buttonChoose.place(x=50,y=10,width=50,height=20)

# 播放按钮
pause_resume = tkinter.StringVar(root,value='播放')
buttonPlay = tkinter.Button(root,textvariable=pause_resume,command=buttonPlayClick)
buttonPlay.place(x=120,y=10,width=50,height=20)
buttonPlay['state'] = 'disabled'



# 下一首
buttonNext = tkinter.Button(root, text='下一首',command=buttonNextClick)
buttonNext.place(x=190, y=10, width=50, height=20)
buttonNext['state'] = 'disabled'
# 上一首
buttonPrev = tkinter.Button(root, text='上一首',command=buttonPrevClick)
buttonPrev.place(x=260, y=10, width=50, height=20)
buttonPrev['state'] = 'disabled'

# 波形图
buttonPic = tkinter.Button(root, text='波形图',command=buttonShowPic)
buttonPic.place(x=330, y=10, width=50, height=20)
buttonPic['state'] = 'disabled'

# 词频统计
buttonFreq = tkinter.Button(root, text='词频统计',command=buttonWordFreq)
buttonFreq.place(x=400, y=10, width=50, height=20)
buttonFreq['state'] = 'disabled'


# 调至
buttonJump = tkinter.Button(root, text='跳至',command=jump_to1)
buttonJump.place(x=470, y=10, width=50, height=20)
buttonJump['state'] = 'disabled'

# 进度条控制
scale1 = tkinter.Scale(root, label='进度', from_=0, to=300, orient=tkinter.HORIZONTAL,
                       length=240, showvalue=0, resolution=1)
scale1.place(x=50, y=50, width=200)



# 音量控制
# HORIZONTAL表示为水平放置，默认为竖直,竖直为vertical
s = tkinter.Scale(root, label='音量', from_=0, to=1, orient=tkinter.HORIZONTAL,
                  length=240, showvalue=0, tickinterval=2, resolution=0.1,command=control_voice)
s.place(x=50, y=100, width=200)



# 显示
root.mainloop()